//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "TAfin.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

TAfin::TAfin(float x11,float x21,float x31, float x41,float x12, float x22, float x32, float x42,
             float x13, float x23, float x33, float x43,float x14, float x24, float x34, float x44){

        m[0]=x11; m[1]=x21; m[2]=x31; m[3]=x41;
        m[4]=x12; m[5]=x22; m[6]=x32; m[7]=x42;
        m[8]=x13; m[9]=x23; m[10]=x33; m[11]=x43;
        m[12]=x14; m[13]=x24;m[14]=x34; m[15]=x44;
}

void TAfin::traslate(PV *v){
        TAfin* matrizTraslacion=new TAfin(1,0,0,0,0,1,0,0,0,0,1,0,v->getX(),v->getY(),v->getZ(),1);
        this->postMulMatriz(matrizTraslacion->m);
        delete matrizTraslacion;
}
void TAfin::rotate(GLfloat ang_grados, PV * vector_de_rotacion){
        GLfloat radianes=ang_grados*M_PI/180;
        GLfloat c=cos(radianes);
        GLfloat s=sin(radianes);
        GLfloat mc=1.0-c;

        GLfloat x = vector_de_rotacion->getX();
        GLfloat y = vector_de_rotacion->getY();
        GLfloat z = vector_de_rotacion->getZ();

        TAfin * matrizRotacion=new TAfin(c+mc*x*x, mc*x*y+s*z, mc*x*z-s*y, 0, mc*y*x-s*z,c+mc*y*y,mc*y*z+s*x,0,mc*z*x+s*y,mc*z*y-s*x,c+mc*z*z,0,0,0,0,1);
        this->postMulMatriz(matrizRotacion->m);
        delete matrizRotacion;
}

void TAfin::scale(GLfloat x,GLfloat y,GLfloat z){
        TAfin* matrizEscalacion=new TAfin(x,0,0,0,0,y,0,0,0,0,z,0,0,0,0,1);
        this->postMulMatriz(matrizEscalacion->m);
        delete matrizEscalacion;
}

void TAfin::postMulMatriz(GLfloat matriz[16]){
        float nuevaMatriz[16];
        for(int i=0;i<4;i++)
                for(int j=0;j<4;j++){
                        float v=0;
                        for(int k=0;k<4;k++){
                                int indice1=4*k+j;
                                int indice2=4*i+k;
                                float v1=m[indice1];
                                float v2=matriz[indice2];
                                v+=v1*v2;
                        }
                        int indice3=4*i+j;
                        nuevaMatriz[indice3]=v;
                }
        for(int i=0;i<16;i++)
              m[i]=nuevaMatriz[i];
}
GLfloat* TAfin::postMulVector(GLfloat vector[4]){


       float *nv =new float [4];

       for(int i=0;i<4;i++){
                    float val=0;
                        for(int k=0;k<4;k++){
                                int indice1=k+4*i;
                                float v1=m[indice1];
                                float v2=vector[k];
                                val+=v1*v2;
                        }

                        nv[i]=val;
                }

       return nv;

}

void TAfin::identidad(){
        m[0]=1; m[1]=0; m[2]=0; m[3]=0;
        m[4]=0; m[5]=1; m[6]=0; m[7]=0;
        m[8]=0; m[9]=0; m[10]=1; m[11]=0;
        m[12]=0; m[13]=0;m[14]=0; m[15]=1;

}
